﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//class Person
//{
//public:
//    virtual void BuyTicket()
//    {
//        cout << "买票-全价" << endl;
//    }
//};
//
//class Student : public Person
//{
//public:
//    virtual void BuyTicket()
//    {
//        cout << "买票-打折" << endl;
//    }
//};
//
//void Func(Person* ptr)
//{
//    // 这⾥可以看到虽然都是Person指针Ptr在调用BuyTicket
//    // 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//    ptr->BuyTicket();
//}
//
//int main()
//{
//    Person ps;
//    Student st;
//    Func(&ps);
//    Func(&st);
//    return 0;
//}

//class Animal
//{
//public:
//	virtual void talk() const
//	{}
//};
//class Dog : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//
//class Cat : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//void letsHear(const Animal& animal)
//{
//	animal.talk();
//}
//int main()
//{
//	Cat cat;
//	Dog dog;
//	letsHear(cat);
//	letsHear(dog);
//	return 0;
//}


//class Person {
//public:
//	void BuyTicket() { cout << "买票-全价" << endl; }
//};
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-打折" << endl; }
//};
//void Func(Person* ptr)
//{
//    // 这⾥可以看到虽然都是Person指针Ptr在调用BuyTicket
//    // 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//    ptr->BuyTicket();
//}
//int main()
//{
//    Person ps;
//    Student st;
//    Func(&ps);
//    Func(&st);
//    return 0;
//}

//class Person {
//public:
//	void BuyTicket() { cout << "买票-全价" << endl; }
//};
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-打折" << endl; }
//};

//class Person {
//public:
//    virtual void BuyTicket() { cout << "买票-全价" << endl; }
//};
//class Student : public Person {
//public:
//    virtual void BuyTicket() { cout << "买票-打折" << endl; }
//};
//
//void Func(Person ptr)
//{
//    ptr->BuyTicket()
//}

//class Person {
//public:
//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
//};
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-打折" << endl; }
//};
//void Func(Student* ptr)
//{
//	ptr->BuyTicket();
//}


//class Person
//{
//public:
//    virtual void BuyTicket()
//    {
//        cout << "买票-全价" << endl;
//    }
//};
//
//class Student : public Person
//{
//public:
//    virtual void BuyTicket()
//    {
//        cout << "买票-打折" << endl;
//    }
//};
//
//void Func(Person* ptr)
//{
//    // 这⾥可以看到虽然都是Person指针Ptr在调用BuyTicket
//    // 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//    ptr->BuyTicket();
//}
//
//int main()
//{
//    Person ps;
//    Student st;
//    Func(&ps);
//    Func(&st);
//    return 0;
//}


//class Animal
//{
//public:
//	virtual void talk() const
//	{}
//};
//class Dog : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//
//class Cat : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//void letsHear(const Animal& animal)
//{
//	animal.talk();
//}
//int main()
//{
//	Cat cat;
//	Dog dog;
//	letsHear(cat);
//	letsHear(dog);
//	return 0;
//}


//class A {};
//class B : public A {};
//class Person {
//public:
//	virtual A* BuyTicket()
//	{
//		cout << "买票-全价" << endl;
//		return nullptr;
//	}
//};
//class Student : public Person {
//public:
//	virtual B* BuyTicket()
//	{
//		cout << "买票-打折" << endl;
//		return nullptr;
//	}
//};
//void Func(Person* ptr)
//{
//	ptr->BuyTicket();
//}
//int main()
//{
//	Person ps;
//	Student st;
//	Func(&ps);
//	Func(&st);
//	return 0;
//}

//class A
//{
//public :
//	 virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//int main()
//{
//	A* p1 = new A;
//	A* p2 = new B;
//	delete p1;
//	delete p2;
//	return 0;
//}


// error C3668: “Benz::Drive”: 包含重写说明符“override”的⽅法没有重写任何基类⽅法
//class Car {
//public:
//	virtual void Dirve()
//	{}
//};
//class Benz :public Car {
//public:
//	virtual void Drive() override { cout << "Benz-舒适" << endl; }
//};
//int main()
//{
//	return 0;
//}

//class Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "hello" << std::endl;
//	}
//};
//
//class Cat : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//class Dog : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//int main()
//{
//	Animal* a = new Animal;
//	Animal* b = new Cat;
//	Animal* c = new Dog;
//	a->talk();
//	b->talk();
//	c->talk();
//
//	return 0;
//}
//
//void func(Animal* ptr)
//{
//	ptr->talk();
//}
//int main()
//{
//
//	//Cat* cat = new Cat;
//	//cat->talk();
//
//
//	//Dog dog;
//	//Dog* pdog = &dog;
//	//pdog->talk();
//
//	/*func(cat);
//	func(pdog);*/
//
//	Animal* pCat = new Cat;
//	Animal* pDog = new Dog;
//	func(pCat);
//	func(pDog);
//	
//	return 0;
//}
//int main()
//{
//	Animal* pCat = new Cat;
//	Animal* pDog = new Dog;
//	pCat->talk();
//	pDog->talk();
//
//	return 0;
//}
//
//
//class Car
//{
//public :
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//
//};


//class Car
//{
//public :
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//public :
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//class BMW :public Car
//{
//public :
//	virtual void Drive()
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//
//int main()
//{
//	Car* pBenz = new Benz;
//	pBenz->Drive();
//
//	Car* pBMW = new BMW;
//	pBMW->Drive();
//
//	return 0;
//}


//class Animal
//{
//public:
//	virtual void talk() const
//	{}
//};
//class Dog : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//
//class Cat : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//
//int main()
//{
//	Cat* pcat = new Cat;
//	Dog* pdog = new Dog;
//
//	pcat->talk();
//	pdog->talk();
//	return 0;
//}

//class A
//{
//public:
//	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//	virtual void test() { func(); }
//};
//class B : public A
//{
//public:
//	void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//};
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//	//p->test();
//	p->func();
//	return 0;
//}


//class Base
//{
//public :
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//
//	virtual void Func2()
//	{
//		cout << "Func2()" << endl;
//	}
//
//	void Func3()
//	{
//		cout << "Func3()" << endl;
//	}
//
//protected:
//	int _b = 1;
//	char _ch = 'x';
//};
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//	return 0;
//}


//class Person {
//public:
//	void BuyTicket() { cout << "买票-全价" << endl; }
//protected:
//	string _name;
//};
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-打折" << endl; }
//protected:
//	int _id;
//};
//class Soldier : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-优先" << endl; }
//protected:
//	string _codename;
//};
//void Func(Person* ptr)
//{
//	ptr->BuyTicket();
//} 
//int main()
//{
//	Person ps;
//	Student st;
//	Soldier sr;
//	Func(&ps);
//	Func(&st);
//	Func(&sr);
//	return 0;
//}


//// ptr是指针+BuyTicket是虚函数满⾜多态条件。
//// 这⾥就是动态绑定，编译在运⾏时到ptr指向对象的虚函数表中确定调⽤函数地址
//ptr->BuyTicket();
//00EF2001 mov eax, dword ptr[ptr]
//00EF2004 mov edx, dword ptr[eax]
//00EF2006 mov esi, esp
//00EF2008 mov ecx, dword ptr[ptr]
//00EF200B mov eax, dword ptr[edx]
//00EF200D call eax
//
//// BuyTicket不是虚函数，不满⾜多态条件。
//// 这⾥就是静态绑定，编译器直接确定调⽤函数地址
//ptr->BuyTicket();
//00EA2C91 mov ecx, dword ptr[ptr]
//00EA2C94 call Student::Student(0EA153Ch)

	
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//
//	virtual void Func2()
//	{
//		cout << "Func2()" << endl;
//	}
//
//protected:
//	int _b = 1;
//	char _ch = 'x';
//};
//int main()
//{
//	Base b1;
//	Base b2;
//	Base b3;
//	return 0;
//}

class Base {
public:
	virtual void func1() { cout << "Base::func1" << endl; }
	virtual void func2() { cout << "Base::func2" << endl; }
	void func5() { cout << "Base::func5" << endl; }
protected:
	int a = 1;
};
class Derive : public Base
{
public :
	// 重写基类的func1
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func1" << endl; }
	void func4() { cout << "Derive::func4" << endl; }
protected:
	int b = 2;
};
int main()
{
	int i = 0;
	static int j = 1;
	int* p1 = new int;
	const char* p2 = "xxxxxxxx";
	printf("栈:%p\n", &i);
	printf("静态区:%p\n", &j);
	printf("堆:%p\n", p1);
	printf("常量区:%p\n", p2);
	Base b;
	Derive d;
	Base* p3 = &b;
	Derive* p4 = &d;
	printf("Person虚表地址:%p\n", *(int*)p3);
	printf("Student虚表地址:%p\n", *(int*)p4);
	printf("虚函数地址:%p\n", &Base::func1);
	printf("普通函数地址:%p\n", &Base::func5);
	return 0;
}
